package com.example.uploadattachment.sftp;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @author 何逸诚
 * @date 2025/3/19 8:35
 * @description SFTP连接工厂
 */
@Slf4j
@Component
public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {
    @Value("${sftp.host}")
    private String host;

    @Value("${sftp.port}")
    private int port;

    @Value("${sftp.username}")
    private String username;

    @Value("${sftp.password}")
    private String password;

    @Override
    public ChannelSftp create() throws Exception {
        JSch jsch = new JSch();
        Session session = jsch.getSession(username, host, port);
        session.setPassword(password);
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();

        ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
        channel.connect();
        return channel;
    }

    @Override
    public PooledObject<ChannelSftp> wrap(ChannelSftp channel) {
        return new DefaultPooledObject<>(channel);
    }

    @Override
    public void destroyObject(PooledObject<ChannelSftp> p) {
        ChannelSftp channel = p.getObject();
        if (channel.isConnected()) {
            channel.disconnect();
        }
        try {
            if (channel.getSession().isConnected()) {
                channel.getSession().disconnect();
            }
        } catch (JSchException e) {
            log.error("连接关闭失败 = {}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean validateObject(PooledObject<ChannelSftp> p) {
        ChannelSftp channel = p.getObject();
        try {
            log.info("channel.isConnected() = {} | channel.getSession().isConnected() = {} ", channel.isConnected(), channel.getSession().isConnected());
            return channel.isConnected() && channel.getSession().isConnected();
        } catch (JSchException e) {
            log.error("检查连接状态失败 = {}", e.getMessage());
            throw new RuntimeException(e);
        }
    }
}
